Apgūstiet TypeScript deklarāciju failus (.d.ts), lai nodrošinātu tipu drošību un automātisko pabeigšanu jebkurai JavaScript bibliotēkai. Iemācieties lietot @types un veidot paši savas definīcijas.
JavaScript Ekosistēmas Atklāšana: Dziļa Ieniršana TypeScript Deklarāciju Failos
TypeScript ir revolucionizējis mūsdienu tīmekļa izstrādi, ienesot statisko tipēšanu dinamiskajā JavaScript pasaulē. Šī tipu drošība sniedz neticamas priekšrocības: kļūdu notveršana kompilēšanas laikā, jaudīgas redaktora automātiskās pabeigšanas funkcijas un lielu kodu bāzu uzturēšanas ievērojama atvieglošana. Tomēr liels izaicinājums rodas, kad mēs vēlamies izmantot plašo esošo JavaScript bibliotēku ekosistēmu — no kurām lielākā daļa nav rakstīta TypeScript. Kā mūsu stingri tipētais TypeScript kods saprot formas, funkcijas un mainīgos no netipētas JavaScript bibliotēkas?
Atbilde slēpjas TypeScript Deklarāciju Failos. Šie faili, kas atpazīstami pēc to .d.ts paplašinājuma, ir būtisks tilts starp TypeScript un JavaScript pasaulēm. Tie darbojas kā projekts vai API līgums, aprakstot trešās puses bibliotēkas tipus, bet nesaturot tās faktisko implementāciju. Šajā visaptverošajā ceļvedī mēs izpētīsim visu, kas jums jāzina, lai pārliecinoši pārvaldītu tipu definīcijas jebkurai JavaScript bibliotēkai jūsu TypeScript projektos.
Kas Tieši Ir TypeScript Deklarāciju Faili?
Iedomājieties, ka esat nolīguši darbuzņēmēju, kurš runā tikai citā valodā. Lai ar viņu efektīvi strādātu, jums būtu nepieciešams tulks vai detalizēts instrukciju kopums valodā, ko jūs abi saprotat. Deklarācijas fails kalpo tieši šim mērķim TypeScript kompilatoram (darbuzņēmējam).
.d.ts fails satur tikai informāciju par tipiem. Tas ietver:
- Funkciju un metožu parakstus (parametru tipi, atgrieztie tipi).
- Mainīgo un to tipu definīcijas.
- Saskarnes (interfaces) un tipu aizstājvārdus (type aliases) sarežģītiem objektiem.
- Klašu definīcijas, ieskaitot to īpašības un metodes.
- Nosaukumvietu (namespace) un moduļu struktūras.
Būtiski, ka šie faili nesatur izpildāmu kodu. Tie ir paredzēti tikai statiskai analīzei. Kad jūs importējat JavaScript bibliotēku, piemēram, Lodash, savā TypeScript projektā, kompilators meklē atbilstošu deklarācijas failu. Ja tas to atrod, tas var validēt jūsu kodu, nodrošināt inteliģentu automātisko pabeigšanu un pārliecināties, ka jūs izmantojat bibliotēku pareizi. Ja tas to neatrod, tas izsauks kļūdu, piemēram: Could not find a declaration file for module 'lodash'.
Kāpēc Deklarāciju Faili Ir Neaizstājami Profesionālā Izstrādē
JavaScript bibliotēku izmantošana bez pienācīgām tipu definīcijām TypeScript projektā grauj pašu iemeslu, kāpēc vispār izmantot TypeScript. Apskatīsim vienkāršu scenāriju, izmantojot populāro utilītu bibliotēku, Lodash.
Pasaule Bez Tipu Definīcijām
Bez deklarācijas faila TypeScript nav ne jausmas, kas ir lodash vai ko tas satur. Lai vispār panāktu koda kompilēšanos, jūs varētu būt kārdināts izmantot ātru risinājumu, piemēram, šo:
const _: any = require('lodash');
const users = [{ 'user': 'barney' }, { 'user': 'fred' }];
// Automātiskā pabeigšana? Šeit palīdzības nav.
// Tipu pārbaude? Nē. Vai 'username' ir pareizā īpašība?
// Kompilators to atļauj, bet izpildes laikā tas var neizdoties.
_.find(users, { username: 'fred' });
Šajā gadījumā _ mainīgais ir ar tipu any. Tas faktiski pasaka TypeScript: "Nepārbaudi neko, kas saistīts ar šo mainīgo." Jūs zaudējat visas priekšrocības: nav automātiskās pabeigšanas, nav argumentu tipu pārbaudes un nav pārliecības par atgriezto tipu. Tā ir augsne izpildlaika kļūdām.
Pasaule Ar Tipu Definīcijām
Tagad apskatīsim, kas notiek, kad mēs nodrošinām nepieciešamo deklarācijas failu. Pēc tipu instalēšanas (ko mēs apskatīsim tālāk), pieredze ir pārveidota:
import _ from 'lodash';
interface User {
user: string;
active?: boolean;
}
const users: User[] = [{ 'user': 'barney' }, { 'user': 'fred' }];
// 1. Redaktors nodrošina automātisko pabeigšanu 'find' un citām lodash funkcijām.
// 2. Uzejot ar kursoru uz 'find', tiek parādīts pilns tās paraksts un dokumentācija.
// 3. TypeScript redz, ka `users` ir `User` objektu masīvs.
// 4. TypeScript zina, ka `find` predikātam uz `User[]` jāietver `user` vai `active`.
// PAREIZI: TypeScript ir apmierināts.
const fred = _.find(users, { user: 'fred' });
// KĻŪDA: TypeScript pamana kļūdu!
// Īpašība 'username' neeksistē tipam 'User'.
const betty = _.find(users, { username: 'betty' });
Atšķirība ir kā diena pret nakti. Mēs iegūstam pilnīgu tipu drošību, izcilu izstrādātāja pieredzi, pateicoties rīkiem, un dramatisku potenciālo kļūdu samazinājumu. Tas ir profesionālais standarts darbam ar TypeScript.
Tipu Definīciju Atrašanas Hierarhija
Tātad, kā jūs iegūstat šos maģiskos .d.ts failus savām iecienītākajām bibliotēkām? Pastāv labi izveidots process, kas aptver lielāko daļu scenāriju.
1. Solis: Pārbaudiet, Vai Bibliotēka Iekļauj Savus Tipus
Labākais scenārijs ir, ja bibliotēka ir rakstīta TypeScript valodā vai tās uzturētāji nodrošina oficiālus deklarāciju failus tajā pašā paketē. Tas kļūst arvien biežāk sastopams mūsdienīgos, labi uzturētos projektos.
Kā pārbaudīt:
- Instalējiet bibliotēku kā parasti:
npm install axios - Ieskaties bibliotēkas mapē
node_modules/axios. Vai redzat kādus.d.tsfailus? - Pārbaudiet bibliotēkas
package.jsonfailu, meklējot lauku"types"vai"typings". Šis lauks norāda tieši uz galveno deklarācijas failu. Piemēram, Axiospackage.jsonsatur:"types": "index.d.ts".
Ja šie nosacījumi ir izpildīti, darbs ir paveikts! TypeScript automātiski atradīs un izmantos šos iekļautos tipus. Nekādas papildu darbības nav nepieciešamas.
2. Solis: DefinitelyTyped Projekts (@types)
Tūkstošiem JavaScript bibliotēku, kas neiekļauj savus tipus, globālā TypeScript kopiena ir izveidojusi neticamu resursu: DefinitelyTyped.
DefinitelyTyped ir centralizēta, kopienas pārvaldīta repozitorija GitHub, kurā tiek glabāti augstas kvalitātes deklarāciju faili milzīgam skaitam JavaScript pakešu. Šīs definīcijas tiek publicētas npm reģistrā zem @types tvēruma (scope).
Kā to izmantot:
Ja bibliotēka, piemēram, lodash, neiekļauj savus tipus, jūs vienkārši instalējat tās atbilstošo @types paketi kā izstrādes atkarību (development dependency):
npm install --save-dev @types/lodash
Nosaukumu piešķiršanas konvencija ir vienkārša un paredzama: paketei ar nosaukumu package-name tās tipi gandrīz vienmēr būs pieejami kā @types/package-name. Jūs varat meklēt pieejamos tipus npm vietnē vai tieši DefinitelyTyped repozitorijā.
Kāpēc --save-dev? Deklarāciju faili ir nepieciešami tikai izstrādes un kompilēšanas laikā. Tie nesatur nekādu izpildlaika kodu, tāpēc tos nevajadzētu iekļaut jūsu gala produkcijas paketē (bundle). To instalēšana kā devDependency nodrošina šo nodalīšanu.
3. Solis: Kad Tipi Neeksistē – Rakstiet Savus
Ko darīt, ja izmantojat vecāku, nišas vai iekšēju privātu bibliotēku, kas neiekļauj tipus un nav atrodama DefinitelyTyped? Šādā gadījumā jums ir jāatrot piedurknes un jāizveido pašam savs deklarācijas fails. Lai gan tas var izklausīties biedējoši, jūs varat sākt ar vienkāršu un pievienot vairāk detaļu pēc nepieciešamības.
Ātrais Risinājums: Saīsināta Apkārtējā Moduļa Deklarācija
Dažreiz jums vienkārši nepieciešams panākt, lai jūsu projekts kompilētos bez kļūdām, kamēr jūs izdomājat pareizu tipēšanas stratēģiju. Jūs varat izveidot failu savā projektā (piemēram, declarations.d.ts vai types/global.d.ts) un pievienot saīsinātu deklarāciju:
// .d.ts failā
declare module 'some-untyped-library';
Tas pasaka TypeScript: "Uzticies man, modulis ar nosaukumu 'some-untyped-library' pastāv. Vienkārši uzskati visu, kas no tā tiek importēts, kā tipu any." Tas apklusina kompilatora kļūdu, bet, kā mēs jau apspriedām, tas upurē visu tipu drošību šai bibliotēkai. Tas ir īslaicīgs lāpījums, nevis ilgtermiņa risinājums.
Pamata Pielāgota Deklarācijas Faila Izveide
Labāka pieeja ir sākt definēt tipus tām bibliotēkas daļām, kuras jūs faktiski izmantojat. Pieņemsim, ka mums ir vienkārša bibliotēka ar nosaukumu `string-utils`, kas eksportē vienu funkciju.
// Fails: node_modules/string-utils/index.js
module.exports.capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
Mēs varam izveidot string-utils.d.ts failu speciālā `types` direktorijā mūsu projekta saknes mapē.
// Fails: my-project/types/string-utils.d.ts
declare module 'string-utils' {
export function capitalize(str: string): string;
// Šeit varat pievienot citas funkciju definīcijas, kad tās izmantojat
// export function slugify(str: string): string;
}
Tagad mums ir jāpasaka TypeScript, kur atrast mūsu pielāgotās tipu definīcijas. Mēs to darām tsconfig.json:
{
"compilerOptions": {
// ... citas opcijas
"baseUrl": ".",
"paths": {
"*": ["types/*"]
}
}
}
Ar šādu iestatījumu, kad jūs izmantojat import { capitalize } from 'string-utils', TypeScript atradīs jūsu pielāgoto deklarācijas failu un nodrošinās jūsu definēto tipu drošību. Jūs varat pakāpeniski papildināt šo failu, izmantojot arvien vairāk bibliotēkas funkciju.
Iedziļināšanās: Deklarāciju Failu Izveide
Izpētīsim dažus sarežģītākus konceptus, ar kuriem jūs saskarsieties, rakstot vai lasot deklarāciju failus.
Dažādu Eksporta Veidu Deklarēšana
JavaScript moduļi var eksportēt lietas dažādos veidos. Jūsu deklarācijas failam ir jāatbilst bibliotēkas eksporta struktūrai.
- Nosauktie Eksporti (Named Exports): Šis ir visizplatītākais veids. Mēs to redzējām iepriekš ar `export function capitalize(...)`. Jūs varat arī eksportēt konstantes, saskarnes un klases.
- Noklusējuma Eksports (Default Export): Bibliotēkām, kas izmanto `export default`.
- UMD Globālie Mainīgie: Vecākām bibliotēkām, kas paredzētas darbam pārlūkprogrammās, izmantojot
<script>tagu, tās bieži pievieno sevi globālajam `window` objektam. Jūs varat deklarēt šos globālos mainīgos. export =unimport = require(): Šī sintakse ir paredzēta vecākiem CommonJS moduļiem, kas izmanto `module.exports = ...`. Piemēram, ja bibliotēka veic `module.exports = myClass;`.
declare module 'my-lib' {
export const version: string;
export interface Options { retries: number; }
export function doSomething(options: Options): Promise
declare module 'my-default-lib' {
// Funkcijas noklusējuma eksportam
export default function myCoolFunction(): void;
// Objekta noklusējuma eksportam
// const myLib = { name: 'lib', version: '1.0' };
// export default myLib;
}
// Deklarē globālu mainīgo '$' ar noteiktu tipu
declare var $: JQueryStatic;
// fails: my-class.d.ts
declare class MyClass { constructor(name: string); }
export = MyClass;
// fails: your app.ts
import MyClass = require('my-class');
const instance = new MyClass('test');
Lai gan tas ir retāk sastopams ar mūsdienu ES moduļiem, tas ir kritiski svarīgi saderībai ar daudzām vecākām, bet joprojām plaši izmantotām Node.js paketēm.
Moduļu Papildināšana: Esošo Tipu Paplašināšana
Viena no jaudīgākajām funkcijām ir moduļu papildināšana (pazīstama arī kā deklarāciju apvienošana). Tā ļauj jums pievienot īpašības esošām saskarnēm, kas definētas citas paketes deklarācijas failā. Tas ir ļoti noderīgi bibliotēkām ar spraudņu (plugin) arhitektūru, piemēram, Express vai Fastify.
Iedomājieties, ka jūs izmantojat starpprogrammatūru (middleware) Express, kas pievieno `user` īpašību `Request` objektam. Bez papildināšanas TypeScript sūdzētos, ka `user` neeksistē uz `Request`.
Lūk, kā jūs varat informēt TypeScript par šo jauno īpašību:
// jūsu types/express.d.ts failā
// Mums ir jāimportē oriģinālais tips, lai to papildinātu
import { UserProfile } from './auth'; // Pieņemot, ka jums ir UserProfile tips
// Paziņojam TypeScript, ka mēs papildinām 'express-serve-static-core' moduli
declare module 'express-serve-static-core' {
// Mērķējam uz 'Request' saskarni šajā modulī
interface Request {
// Pievienojam mūsu pielāgoto īpašību
user?: UserProfile;
}
}
Tagad visā jūsu lietojumprogrammā Express `Request` objekts būs pareizi tipēts ar opcionālo `user` īpašību, un jūs iegūsiet pilnu tipu drošību un automātisko pabeigšanu.
Trīskāršās Slīpsvītras Direktīvas
Jūs dažreiz varat redzēt komentārus .d.ts failu augšpusē, kas sākas ar trim slīpsvītrām (///). Tās ir trīskāršās slīpsvītras direktīvas, kas darbojas kā kompilatora instrukcijas.
/// <reference types="..." />: Šī ir visizplatītākā. Tā nepārprotami iekļauj citas paketes tipu definīcijas kā atkarību. Piemēram, WebdriverIO spraudņa tipi varētu ietvert/// <reference types="webdriverio" />, jo tā paša tipi ir atkarīgi no galvenajiem WebdriverIO tipiem./// <reference path="..." />: To izmanto, lai deklarētu atkarību no cita faila tajā pašā projektā. Tā ir vecāka sintakse, ko lielā mērā ir aizstājuši ES moduļu importi.
Labākā Prakse Deklarāciju Failu Pārvaldībā
- Dodiet Priekšroku Iekļautajiem Tipiem: Izvēloties starp bibliotēkām, dodiet priekšroku tām, kas ir rakstītas TypeScript vai iekļauj savas oficiālās tipu definīcijas. Tas liecina par apņemšanos atbalstīt TypeScript ekosistēmu.
- Turiet
@typeszemdevDependencies: Vienmēr instalējiet@typespaketes ar--save-devvai-D. Tās nav nepieciešamas jūsu produkcijas kodam. - Saskaņojiet Versijas: Biežs kļūdu avots ir neatbilstība starp bibliotēkas versiju un tās
@typesversiju. Būtiskas versijas izmaiņas bibliotēkā (piemēram, no v2 uz v3), visticamāk, radīs izmaiņas tās API, kam jāatspoguļojas@typespaketē. Centieties tās uzturēt sinhronizētas. - Izmantojiet
tsconfig.jsonKontrolei: Kompilatora opcijastypeRootsuntypesjūsutsconfig.jsonfailā var sniegt jums precīzu kontroli pār to, kur TypeScript meklē deklarāciju failus.typeRootsnorāda kompilatoram, kuras mapes pārbaudīt (pēc noklusējuma tā ir./node_modules/@types), untypesļauj jums skaidri norādīt, kuras tipu paketes iekļaut. - Sniedziet Savu Ieguldījumu: Ja jūs uzrakstāt visaptverošu deklarācijas failu bibliotēkai, kurai tāda nav, apsveriet iespēju to pievienot DefinitelyTyped projektam. Tas ir fantastisks veids, kā atdot globālajai izstrādātāju kopienai un palīdzēt tūkstošiem citu.
Noslēgums: Tipu Drošības Neapdziedātie Varoņi
TypeScript Deklarāciju Faili ir neapdziedātie varoņi, kas ļauj netraucēti integrēt dinamisko, plašo JavaScript pasauli stabilā, tipu drošā izstrādes vidē. Tie ir kritiski svarīgā saikne, kas dod spēku mūsu rīkiem, novērš neskaitāmas kļūdas un padara mūsu kodu bāzes noturīgākas un pašdokumentējošas.
Saprast, kā atrast, izmantot un pat izveidot savus .d.ts failus, nozīmē ne tikai novērst kompilatora kļūdu — tas paceļ visu jūsu izstrādes darbplūsmu jaunā līmenī. Jūs atraisāt pilnu potenciālu gan TypeScript, gan bagātīgajai JavaScript bibliotēku ekosistēmai, radot spēcīgu sinerģiju, kas rezultējas labākā, uzticamākā programmatūrā globālai auditorijai.